AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Timer direkt aufrufen

Ein Thema von Go2EITS · begonnen am 21. Okt 2006 · letzter Beitrag vom 21. Okt 2006
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#11

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 11:10
Zitat von kolbaschedder:
procedure MachIrgendwas(Sender :TObject);
Wozu der Parameter Sender? Was macht er? Wofür brauchen wir ihn?
Jeder Aufruf einer TNotifyEvent-Prozedur ist unsauber, ist sie nicht ein Eventhandler einer Komponente.
Zitat von kolbaschedder:
dann kannst du sogar anhand des Senders unterscheiden, wer dich aufgerufen hat
Dann hast du die Trennung von GUI und Code nicht begriffen. Will ich mehrere Anweisungen mehrmals in verschiedenen Codestellen aufrufen (hier also einmal als Eventhandler und einmal direkt im OnShow-Code), muss ich sie als Aufgabe kapseln. Diese Aufgabe=Prozedur kann eine beliebige Anzahl von Parametern haben, aber auf keinen Fall einen Sender-Parameter, weil es ihr einfach egal ist/sein muss, von welcher Komponente sie aufgerufen wird; in der Code-Ebene sind Komponenten schließlich einfach nichtexistent.

[edit]
Zitat von Balu der Bär:
Letztendlich ist es doch völlig egal ob es nun sauber oder unsauber ist, hauptsache der Programmierer kommt damit klar. Wenn mehrere Leute mit dem Quelltexten arbeiten sollten wäre es aber wohl doch etwas strange.
Nun, in gewissem Maße ist dies hier ein Ort, bei dem viele Leute mit dem Quelltext arbeiten und er deshalb nicht allzu strange sein sollte .
[/edit]
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Go2EITS

Registriert seit: 25. Jun 2006
519 Beiträge
 
Delphi 7 Personal
 
#12

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 11:12
@fwsp
Das wollte ich nicht. Doppelter Code vergroßert unnötig die EXE.

@kolbaschedder
Genauso geht es.

@3_of_8

Prinzipell magst Du recht haben. Das Problem hatten wir schon mit den Aufruf von Button1.click.
Zitat:
OnTimer bedeutet für mich "das Ereignis, das aufgerufen wird, wenn der Timer abläuft" und nicht "das Ereignis, das aufgerufen wird, wenn der Timer abläuft und manchmal auch zwischendurch, wenn der Programmierer grad Lust drauf hat".
Und ich bin der Meinung, da die Routinen im Timer genau so abzuarbeiten sind, halte ich, nur um sauber zu arbeiten, eine Auslagerung der Routinen nicht für sinnvoll. Der Timer wird nur einmalig aufgerufen, ist währenddessen nicht aktiv und läuft dann "normal". Igendwelche Seiteneffekte oder undefinierte Programmzustände sind in meinem Fall ausgeschlossen.

Zitat:
Routinen- und Methodenbezeichner müssen mehr oder weniger selbsterklärend sein.
Ist er: Timer1

@Daniel
Ihr seid erfahrener. Offen gesagt, meine Button1.click Aufrufe machten mir überhaupt keine Probleme
im Projekt Delphi Cleaner. Nicht ein einziger Fehler/BUG war darauf zurückzuführen. Für mich zählt Praxis, nicht Theorie. Das Einzige was mich wunderte, war ein dass ein Checkbox1.checked:=StrToBool(h); die Checkbox1.click Methode aufgerufen hat... Aber das ist eine andere Frage.

Zitat:
dann schreiben wir eben eine Methode

procedure MachIrgendwas(Sender :TObject);

in der formCreate dann

Timer1.OnTimer := MachIrgendwas;
Grins... So kann man es auch machen.

Vielen Dank für die Antworten. Das Problem ist für mich gelöst. Top!
Go2EITS
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#13

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 11:33
Vielleicht ist das genau das Problem: In der Praxis geht es durchaus, so wie Du das beschreibst. Zumindest erstmal ...


Auch wenn Du Deinen Fokus lieber auf die Praxis legst, möchte ich ein wenig Theorie beisteuern:


Eine Methode sollte einen definierten Zweck haben. Und zwar genau einen. Aus diesem Zweck ergibt sich in den meisten Fällen auch ein brauchbarer Name für die Methode. Hier hat man auch eine schnelle Möglichkeit zur selbstkritischen Kontrolle: Wenn einem auf Teufel komm raus kein brauchbarer Name für eine Methode einfallen mag, so ist das ein ganz deutliches Indiz dafür, diese Methode zu überdenken und den Code ggf. anders zu strukturieren.

Button1.Click() ist die Methode, die aufgerufen wird, wenn die zugehörige Schaltfläche gedrückt wird. Fertig aus. Diese Methode hat eine sehr enge Bindung zu Deiner Programmoberfläche und man kann sie als Teil derselbigen ansehen. Der Klick auf den Button soll ja etwas auslösen und das sollte diese Methode deligieren. Wenn jetzt in Deinem Datenmodell etwas verändert werden soll, zum Beispiel eine Variable gesetzt werden soll, dann hast Du eine Methode, die sich darum kümmert und etwaige Plausibilitäts-prüfungen vornimmt. Das aber hat mit dem Button nichts mehr zutun. Die Variable könntest Du auch ändern, wenn Dein Programm zum Beispiel über ein Script gesteuert wird. Auch dann müsstest Du ja etwaige Plausibilitäten rund um diese Variable prüfen. Das kannst Du nur dann erreichen, wenn Du den Code kapselst. Alleine durch die Kapselung von Code holst Du Dir auch keine negativen Seiteneffekte ins Haus.

Nun kannst Du jetzt sagen: "Ach was, läuft doch" - und hast in Deinem Fall sogar Recht damit. Mir ist es gleich, wie Du Deinen Code schreibst und ich will jetzt nicht sagen "Du musst, Du musst, Du musst...". Aber als Denk-Anstoß solltest Du das mitnehmen. Ich bin ja nicht der einzige, der so denkt. Das Ding is', dass sich diese Denkweise in der Software-Entwicklung weitgehend etabliert hat.

Stichworte wären: "Kopplung von Modulen", in diesem Zusammenhang auch "Trennung von GUI und Programm-Logik" oder aber das gute alte "Model-View-Controler"-Prinzip. Selbst verständlich steht es Euch frei, zu entwickeln, wie Ihr mögt - aber unternehmt bitte nicht den aussichtslosen Versuch, o.g. Konzepte mit einem Satz allgemeingültig wegzuwischen.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#14

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 11:47
Zitat von Go2EITS:
@fwsp
Das wollte ich nicht. Doppelter Code vergroßert unnötig die EXE.
Zitat von Go2EITS:
Zitat:
procedure MachIrgendwas(Sender :TObject);

in der formCreate dann

Timer1.OnTimer := MachIrgendwas;
Grins... So kann man es auch machen.
Äh, wo siehst du denn hier den Unterschied? Du hast in beiden Fällen die eigentliche Abarbeitung ausgelagert. Einmal verwendest du noch einen Methodenzeiger auf die Prozedur, aber da hatte fwsp sich ja nicht festgelegt.
Nebenbei hat auslagern nichts mit doppelten Code zu tun! Doppelter (gleicher) Code wäre tatsächlich völlig unangebracht. Aber auslagern heißt nur, dass du für die Lösung eines Problems eine Methode verwendest. Typischerweise lagert man Code aus, um ebend doppelten Code zu vermeiden.
Das deine Exe um ein paar Byte größer wird und du auch noch ein paar nanosekunden für den Aufruf der Prozedur verlierst, wirst du kaum merken!

Und ich bin der Meinung, da die Routinen im Timer genau so abzuarbeiten sind, halte ich, nur um sauber zu arbeiten, eine Auslagerung der Routinen nicht für sinnvoll. Der Timer wird nur einmalig aufgerufen, ist währenddessen nicht aktiv und läuft dann "normal". Igendwelche Seiteneffekte oder undefinierte Programmzustände sind in meinem Fall ausgeschlossen.

Zitat von Go2EITS:
Und ich bin der Meinung, da die Routinen im Timer genau so abzuarbeiten sind, halte ich, nur um sauber zu arbeiten, eine Auslagerung der Routinen nicht für sinnvoll. Der Timer wird nur einmalig aufgerufen, ist währenddessen nicht aktiv und läuft dann "normal". Igendwelche Seiteneffekte oder undefinierte Programmzustände sind in meinem Fall ausgeschlossen.
Wow, du hast keine Ahnung wovon du da redest, oder? Warum genau hälst du bitte die Auslagerung von Routinen nicht für sinnvoll? Und wie kommst du auf die Idee, dass du Seiteneffekte oder undefinierte Programmzustände ausschließen könntest?
Möchtest du Seiteneffekte ausschließen, dann solltest du funktional Programmieren. Schau dir mal sowas wie Haskell an, da gibt es dann auch die Lazy-Evaluation. Die ist immer ein eindeutiges Zeichen dafür, dass es keine Seiteneffekte (eben auch keine Zustände) geben kann. Da du aber imperativ bis Objekt Orientiert arbeitest, existieren Zustände, ergo sind Seiteneffekte durchaus möglich.
Ob sie (ungewollt) auftreten oder nicht ist dann so eine Sache, genau wie undefinierte Programmzustände hat das aber wenig damit zu tun, wie du hier die Methode aufrufst.

Das Timer1 weder ein Routinen noch ein Methodenbezeichner ist, ist dir doch hoffentlich klar?!

Zitat von Go2EITS:
@Daniel
Ihr seid erfahrener. Offen gesagt, meine Button1.click Aufrufe machten mir überhaupt keine Probleme
im Projekt Delphi Cleaner. Nicht ein einziger Fehler/BUG war darauf zurückzuführen. Für mich zählt Praxis, nicht Theorie. Das Einzige was mich wunderte, war ein dass ein Checkbox1.checked:=StrToBool(h); die Checkbox1.click Methode aufgerufen hat... Aber das ist eine andere Frage.
Was möchtest du nun wiederum damit sagen. Sicherlich ist Daniel erfahrener als du (sorry, aber das merkt man einfach schnell). Schön dass du das anerkennst, aber warum genau ignorierst du dann was er zu sagen hat? (gilt auch für die anderen Beiträge). Du hast in irgendeinem Projekt nicht einen Fehler/BUG auf Button1.click zurückführen können, toll! Wieviele waren auf Button2.Click zurück zu führen?
Weißt du, ein paar wichtige Ziele gibt es für jede Software, da wären unter anderem immer Robustheit, Sicherheit, Erweiterbarkeit und Wartbarkeit (und noch viele viele mehr). Nehmen wir mal die letzten beiden, Erweiterbarkeit und Wartbarkeit haben viel miteinander gemeinsam. Sagen wir der Delphi Cleaner (was auch immer der kann) wird super erfolgreich und muss erweitert werden. Wer ausser dir wird denn jetzt wissen was Button1.Click macht? Klar, die Anwendung hat vielleicht nur einen Button, aber was ist wenn die 5 hat? Was genau ist dann die Aussage davon, dass Button1 gedrückt wurde? Nebenbei bemerkt wenn du 5 Button in einem Programm hast, dann wirst du in einem halben Jahr auch nicht mehr wissen, welcher Button was machte.

Das der Code funktioniert, das ist nicht die Frage/das Ziel. Du hast sicherlich schon etwas von QuickAndDirty gehört. Man findet immer wieder Leute, die so arbeiten, aber kaum in großen Firmen. Wenn du einen Kunden hast, der ein paar Ansprüche stellt, dann kommst du damit nicht weit. Die Bedürfnisse des Kunden sind in der Regel unscharf (zu Beginn eines Projektes), es gibt das Problem der Kommunikation (was will er wirklich, wie will er es, was will er nicht, ...). Die Entwicklung ist ein agiler Prozess, wenn dein Kunde dein Produkt sieht (einen Zwischenstand), dann kann der noch leicht Änderungswünsche einbringen. Da ist es dann sehr viel einfacher, wenn du die Logik schön ausgelagert hast und alles so benannt ist, dass jeder weiß welche Funktion was tut (und welcher Button wofür zuständig ist). Solltest du mit mehr als einer Person am Projekt arbeiten, ist anders keine Arbeit möglich. Aber auch wenn du allein an einem solchen Projekt sitzt, dadurch dass die einzelnen Problemlösungen ausgelagert sind, musst du kein Copy&Paste anwenden (was sehr fehleranfällig ist) wenn du hier einen Teil änderst.
Nicht zuletzt solltest du auch die GUI von dem Rest trennen, denn gerade das Design ändert sich häufiger als der gesamte Rest.
Natürlich läuft auch jede andere Lösung, aber Änderungswünsche änden schnell in einem Chaos und keine Firma ist bereit sich ewig an einen Entwickler zu binden (weil ausser ihm nie jmd. durch den Code steigen wird).

Gruß Der Unwissende

(Roter Kasten, nur kurz Daniel's Beitrag überflogen, sieht aber nach der gleichen Richtung wie dieser Beitrag aus, wenn auch etwas ausführlicher und schöner von Daniel)
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#15

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 11:56
[Senf]

Sorry wenn ich ein wenig widerspreche.

Für mich ist z.B. der direkte Aufruf Timer1Timer(Timer1); besser lesbar, weil ich hier direkt sehe, dass dort nichts anderes geschieht als beim eigentlichen Timer-Ereignis selbst.

Damit meine ich aber wirklich nur den Fall, dass exakt das gleiche stattfindet.

Sobald in der Routine eine Unterscheidung stattfindet, welcher Sender übergeben wird und ob jetzt wirklich der Timer getriggert hat oder ob die Routine manuell aufgerufen wurde, gebe ich euch wieder Recht: das gehört ausgelagert in eine separate Prozedur.

[/Senf]
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
kolbaschedder

Registriert seit: 24. Aug 2006
Ort: Schwäbisch Gmünd
55 Beiträge
 
Delphi 2006 Professional
 
#16

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 12:16
Hossa,

Da habe ich mit meiner Antwort ja ganz schön was ausgelöst.

In diesem Fall sehe ich es allerdings nicht ganz so tragisch. der Aufruf

Delphi-Quellcode:
Timer1Timer(nil);
Timer1.enabled := true;
ist nun wirklich unproblematisch. Vielleicht wäre die Variante

Delphi-Quellcode:
if not Timer1.enabled then
  Timer1Timer(nil);
end;
Timer1.enabled := true;
Richtiger.

bzw., wäre ein Timer-Objekt mit einer startImmediate-Eigenschaft wünschenswert.


Zu den anderen Dingen muss ich euch recht geben.
Das erste, was man mit einer neuen visuellen Komponente machen sollte, ist, ihr einen sinnvollen NAmen zu geben.
Genauso gehört die Funktionalität des Programms in eigene Methoden. Die GUI sollte diese Funktionalität lediglich steuern.

Bsp.

Delphi-Quellcode:
procedure ParseXML(fName: string);
begin
  ....
end;

procedure btnParseFile.click(sender : TObject);
begin
  if FileExists(currentFile) then
    ParseXML(currentFile)
  else
   application.MessageBox('File not found','Fehler',0);
end;
  Mit Zitat antworten Zitat
Go2EITS

Registriert seit: 25. Jun 2006
519 Beiträge
 
Delphi 7 Personal
 
#17

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 12:19
@Daniel
Besten Dank für Deine Ausführungen. Eine gute Namensgebung ist schon mal eine gute Voraussetzung
für das Gelingen des Projektes. Sie hat mich im Projekt Delphi Cleaner bei der Fehlersuche eine Menge Zeit gekostet, bis ich sinnvolle Namen vergab.

Komplexe Proceduren habe ich dann vereinfacht und gesplittet. Diese Proceduren dann jeweils als Methode jeweils zu implementieren entspricht wohl Deiner Aussage. Dies ist dann wohl die Kapelung, die Du meinst.
Eine
Delphi-Quellcode:
Procedure GoTimer;
begin
form1.timer1.timer(nil)
end;
ist dann nicht zu empfehlen, dann ist wohl die theoretische Lösung der Profis besser:
procedure MachIrgendwas(Sender :TObject); in der formCreate dann
Timer1.OnTimer := MachIrgendwas; wie von kolbaschedder vorgeschlagen.

Ich glaube, ich habe es verstanden.
Beste Grüße an die DP.


[Roter kasten]
Delphi-Quellcode:
procedure TForm1.Timer2Timer(Sender: TObject);
begin
if Silent then Exit;
    form1.label2.Caption:=inttostr(count)+' Files';
    form1.label4.Caption:=bytestostr(size);
    application.processmessages;
end;
sowie meine Auslagerung
Delphi-Quellcode:
procedure TForm1.Machrigendwas(Sender: TObject);
begin
if Silent then Exit;
    form1.label2.Caption:=inttostr(count)+' Files';
    form1.label4.Caption:=bytestostr(size);
    application.processmessages;
end;
verdopplet in dem Falle den Code.


@Der_Unwissende
Zitat:
Was möchtest du nun wiederum damit sagen. Sicherlich ist Daniel erfahrener als du (sorry, aber das merkt man einfach schnell). Schön dass du das anerkennst, aber warum genau ignorierst du dann was er zu sagen hat? (gilt auch für die anderen Beiträge). Du hast in irgendeinem Projekt nicht einen Fehler/BUG auf Button1.click zurückführen können, toll! Wieviele waren auf Button2.Click zurück zu führen?
Weißt du, ein paar wichtige Ziele gibt es für jede Software, da wären unter anderem immer Robustheit, Sicherheit, etc....
Im Gegenteil. Alle wissen das ich Anfänger bin. Das kann man leicht herauslesen und ich mache keinen Hehl daraus. Wenn Du damit User (de-)klassifizierst, spricht es nicht unbedingt für Dich. Jedoch wird es mir zu Offtopic, und, wenn ich mich nicht meine Meinung kundtun darf, oder ehrfürchtig sein, egal vor wem auch immer, muss und dafür von Dir, zumindest zeigt es auch den Ton Deines Beitrages, verbal gemaßregelt werde. Zudem obliegt es Daniel zu reagieren und nicht Dir, und bevormundest Daniel damit auch. Im Bezug, wie ich mich zu Verhalten habe, finde ich doch, sagen wir mal: Ein wenig anmaßend. Ich denke, Du bist mit Deinem Posting ein wenig hinausgeschossen.
Nur weil ich einen Timer oder Buttondirekt aufrufe? Ist es so ein Posting eine Zurechtweisung wert? Damit ist, bei allem Respekt, dieses Thema für mich erledigt, auch wenn in Bezug der der Entwicklung der Software recht hast. Inwieweit ich darüber denke, ist bei Deinem Betrag dann absolut irrelevant.


Go2EITS
  Mit Zitat antworten Zitat
kolbaschedder

Registriert seit: 24. Aug 2006
Ort: Schwäbisch Gmünd
55 Beiträge
 
Delphi 2006 Professional
 
#18

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 12:26
noch richtiger wäre :

Delphi-Quellcode:
procedure Timer1.Timer(Sender: TObject);
begin
  MachirgendWas(Sender);
end;

procedure TForm1.Machrigendwas(Sender: TObject);
begin
if Silent then Exit;
    form1.label2.Caption:=inttostr(count)+' Files';
    form1.label4.Caption:=bytestostr(size);
    application.processmessages;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Sunlight7
Sunlight7

Registriert seit: 17. Sep 2006
Ort: Sonnensystem, Zentral
1.522 Beiträge
 
Delphi 5 Standard
 
#19

Re: Timer direkt aufrufen

  Alt 21. Okt 2006, 14:19
[Noch ein Senf]

Delphi-Quellcode:
// Echter Fake
If Assigned(Timer1.OnTimer) then
   Timer1.OnTimer(Timer1);

// Oder erkennbarer Fake
If Assigned(Timer1.OnTimer) then
   Timer1.OnTimer(nil);
So mach ich das...
Dann weiß man, ob's ein fake Aufruf ist oder nicht

[/Noch ein Senf]
Windows: Ja - Microsoft: Nein -> www.ReactOS.org
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz